package com.itheima;

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.util.Map;


/**
 * 请求体查询-高级别查询
 * 1.布尔查询
 * 2.范围查询
 * 3.模糊查询
 */

@RunWith(SpringRunner.class)
@SpringBootTest
public class Demo05HighLevelSearch {

    //注入高级客户端对象，用来操作es
    @Autowired
    private RestHighLevelClient client;

    /**
     * 目标：布尔查询，多条件组合查询
     * 1.创建请求对象：查询所有
     * 设置索引库name
     * 设置类型type
     * 2.创建查询请求体构建器
     * 设置请求体
     * 3.客户端发送请求，获取响应对象
     * 4.打印响应结果
     */
    @Test
    public void boolQuery() throws IOException {
        //1.创建请求对象
        SearchRequest request = new SearchRequest();
        request.types("_doc");
        request.indices("heima");
        //2.创建查询请求体构建器
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        /*//构建查询方式：布尔查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //必须包含小米
        boolQueryBuilder.must(QueryBuilders.matchQuery("title","小米"));
        //必须不含电视
        boolQueryBuilder.mustNot(QueryBuilders.matchQuery("title","电视"));
        //应该含有手机
        boolQueryBuilder.should(QueryBuilders.matchQuery("title","手机"));
        //设置查询方式
        sourceBuilder.query(boolQueryBuilder)*/
        ;

        /*//构建查询方式：范围查询
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price");
        //大于2千
        rangeQueryBuilder.gt(2000);
        //小于4千
        rangeQueryBuilder.lt(4000);
        //设置查询方式
        sourceBuilder.query(rangeQueryBuilder);*/



        /*   //构建查询方式：模糊查询
        FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("title", "appla");
        //设置偏差值
        fuzzyQueryBuilder.fuzziness(Fuzziness.ONE);
        //设置查询方式
        sourceBuilder.query(fuzzyQueryBuilder);*/


        //sourceBuilder.query(QueryBuilders.matchAllQuery());
        /*
         * 3.查询结果排序
         * */
        //sourceBuilder.sort("price", SortOrder.ASC);

        /*
         *4. 查询结果分页
         * */
        sourceBuilder.size(2);  //每页显示多少条
        sourceBuilder.from(0);  //当前页的起始索引


        /*
         * 5.高亮查询
         * */
        //构建查询方式：高亮查询
        TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("title", "小米");
        //设置查询方式
        sourceBuilder.query(termsQueryBuilder);
        //构建高亮字段
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font color='red'>");//设置标签前缀
        highlightBuilder.postTags("</font>");//设置标签后缀
        highlightBuilder.field("title");//设置高亮字段
        //设置高亮构建对象
        sourceBuilder.highlighter(highlightBuilder);

        //设置请求体
        request.source(sourceBuilder);
        //3.客户端发送请求，获取响应对象
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //4.打印响应结果
        //4.打印响应结果
        SearchHits hits = response.getHits();
        System.out.println("took::" + response.getTook());
        System.out.println("time_out::" + response.isTimedOut());
        System.out.println("total::" + hits.getTotalHits());
        System.out.println("max_score::" + hits.getMaxScore());
        System.out.println("hits::::>>");
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            System.out.println(sourceAsString);
            //打印高亮结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField title = highlightFields.get("title");
            System.out.println("title =:" + title);
        }
        System.out.println("<<::::");
    }
}
